home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
TARFILE.GZ
/
tarfile
/
ch_4.3
/
xah
/
aoi_hist.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
5KB
|
260 lines
/*
* aoi_hist.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/*
* AOI_HIST(ogram).C
*
* routines to evaluate AOI histogram and related quantities
*
*/
#include "xah.h"
#define NBIN_LIM 50
#define N_BINS 51
#define BIN_WIDTH 5
#define MAX_AREA 125 /* refers to special appl */
#define MIN_AREA 0
#undef HIST_DEBUG
/*
* determine mean area
*/
double
eval_mean (int nd, unsigned int *area)
{
int i;
double mean = 0.0;
for (i = 0; i < nd; i++) {
mean += (double) (*(area + i));
}
return (mean / (double) nd);
}
/*
* determine standard deviation of input data set
*/
double
eval_sdev (double mean, int nd, unsigned int *area)
{
int i;
double dai, var = 0.0;
for (i = 0; i < nd; i++) {
dai = (double) (*(area + i)) - mean;
var += (dai * dai);
}
return (sqrt (var /= (double) (nd - 1)));
}
/*
* determine skewness of input data set
*/
double
eval_skew (double mean, double sdev, int nd, unsigned int *area)
{
int i;
double ai, dai, sk;
sk = 0.0;
for (i = 0; i < nd; i++) {
ai = (double) (*(area + i));
dai = (ai - mean) / sdev;
sk += (dai * dai * dai);
}
return ((sk /= (double) nd));
}
/*
* construct histogram of input data
*/
void
construct_hist (int n, float *data, float *hist, double bw, double base)
{
int i, ib;
for (i = 0; i < n; i++) {
if (*(data + i) != 0) {
ib = 0;
while (*(data + i) >= base + ib * bw)
ib++;
*(hist + ib - 1) += 1;
}
}
}
/*
* construct histogram of sorted(!) input data
*/
void
construct_shist (int n, float *data, float *hist, double bw, double base)
{
int i, ib;
ib = 0;
for (i = 0; i < n; i++) {
if (*(data + i) != 0) {
while (*(data + i) >= base + ib * bw)
ib++;
*(hist + ib - 1) += 1;
}
}
}
/*
* determine mean of area histogram in form of centroid:
* (ref: F. Family & P. Meakin, Phys. Rev. A40, 3836-3854 (1989))
*/
double
find_hist_mean (int nb, float *hist, double bw)
{
int ib;
double ssum, sssum, hi;
double mean;
ssum = sssum = 0.0;
for (ib = 0; ib < nb; ib++) {
hi = (double) (*(hist + ib));
ssum += ib * hi;
sssum += ib * ib * hi;
}
if ((-1.0e-10 < ssum) && (ssum < 1.0e-10))
mean = -1.0; /* error */
else
mean = (sssum / ssum) * bw;
return (mean);
}
/*
* prepare to evaluate histogram
*/
struct Histo *
eval_hist (int BIN_METHOD, float *data, int nd, int SRT)
{
#ifdef HIST_DEBUG
int ib;
int id;
#endif
int nb;
double bw, base, range;
struct Histo *h;
switch (BIN_METHOD) {
case DEFAULT:
nb = nd + 1;
base = *(data + 0);
range = *(data + nd - 1) - *(data + 0);
if ((bw = range / (double) nb) < 1.0) { /* for area data */
bw = 1.0;
nb = (int) range;
}
break;
case FIX_BINWD:
bw = (double) BIN_WIDTH;
base = *(data + 0);
range = *(data + nd - 1) - *(data + 0);
while ((nb = (int) (range / (int) bw)) > NBIN_LIM)
bw++;
break;
case FIX_RANGE:
nb = N_BINS;
base = (double) MIN_AREA;
range = (double) MAX_AREA - base;
if (MAX_AREA < *(data + nd - 1)) {
printf ("...WARNING: ");
printf ("max area exceeds currently set upper limit!\n");
}
bw = range / (double) nb;
break;
case FIX_INTERVAL:
nb = N_BINS;
base = 0.0;
range = 2.5;
if (MAX_AREA < *(data + nd - 1)) {
printf ("...WARNING: ");
printf ("max area exceeds currently set upper limit!\n");
}
bw = range / (double) (nb - 1);
break;
default:
printf ("\n...unknown binning method\n");
return ((struct Histo *) NULL);
break;
}
if ((h = (struct Histo *) calloc (1, sizeof (struct Histo))) == NULL)
fail_alloc ("h", 1);
if ((h->ph = (float *) calloc (nb, sizeof (float))) == NULL)
fail_alloc ("h->ph", 1);
#ifdef HIST_DEBUG
printf ("...evaluate histogram: nb = %d, bw = %f\n", nb, bw);
printf ("...input data\n");
for (id = 0; id < nd; id++) {
printf (" %6.2f", *(data + id));
if ((id + 1) % 8 == 0)
printf ("\n");
}
printf ("\n");
#endif
if (SRT == 1) { /* inp data sorted */
construct_shist (nd, data, h->ph, bw, base);
h->amin = *(data + 0); /* min, max inp vals */
h->amax = *(data + nd - 1);
}
else {
construct_hist (nd, data, h->ph, bw, base);
h->amin = (float) -1.0; /* min, max inp vals */
h->amax = (float) -1.0;
}
#ifdef HIST_DEBUG
printf ("...histogram\n");
for (ib = 0; ib < nb; ib++) {
printf (" %4.1f ", h->ph[ib]);
if ((ib + 1) % 10 == 0)
printf ("\n");
}
printf ("\n");
#endif
h->nh = nd;
h->phd = &data[0];
h->mean = -1.0;
h->sdev = -1.0;
h->skew = -1.0;
h->meth = BIN_METHOD;
h->nb = nb;
h->bw = (float) bw;
h->hmean = find_hist_mean (nb, h->ph, bw);
return (h);
}